package a00_ImageGame;

import javax.swing.*;
import javax.swing.border.BevelBorder;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

/**
 * @Author quan
 * @Description 游戏界面
 * @Date 2023/2/14 23:27
 */
/** 移动图片记录0的位置这里不会写，也没看懂
 * 感觉关于以为数组转二位数组那里也很难理解
 */
//长按A(出现新的图片),长按W(直接拼图成功)
/**判断胜利：判断二维数组中的数字是否按照顺序进行排序，如果是是则显示胜利的图片
 * 实现步骤：（1）先定义一个正确的二维数组win；
 * （2）在图片加载之前，先判断一下二维数组中的数字和win数组之中的数字是否一致。 */

/**步数：统计一共移动了多少步 */

/** 关于重新开始游戏：绑定鼠标监听事件
 * （1）给重新游戏绑定事件
 * （2）重新打乱二维数组中的数字
 * （3）加载图片
 * （4）计数器要清零
 * 关闭游戏：（1）给关闭游戏绑定事件；（2）结束虚拟机，关闭所有
 * 公众号：JDalog对象创建，ImageIcon放图片
 */

public class GameJFrame extends JFrame implements KeyListener, ActionListener {
    int[][] arr1 = new int[3][3];//int[][] arr1 = {{1,2,3},{4,5,6},{7,8,9}};
    //记录初始化空白图片的位置
    //-----主要思路：要想实现图片的上下左右移动，遍历二维数组的值：
    // 如果当前值是0，记录下0的位置xy；
    //如果当前值不是0，就正常打乱数字
    int x = 0;
    int y = 0;
    //定义当前路径值
    String path ="D:\\AAQX\\Java\\Project_Practice\\src\\a00_ImageGame\\image\\";
    //win用来存储正确的数字
    int[][] win = {
            {1,2,3},
            {4,5,6},
            {7,8,0}
    };
    //定义步数
    int count;

    //下拉菜单
    JMenuItem replayItem = new JMenuItem("重新游戏");
    JMenuItem reLoginItem = new JMenuItem("重新登录");
    JMenuItem closeItem = new JMenuItem("关闭游戏");

    JMenuItem accountItem = new JMenuItem("公众号");
    public GameJFrame(){
        initJFrame();//Ctrl Alt M 抽取成方法 初始化界面属性
        initJMenuBar();//初始化菜单
        shuffleImage();//打乱图片顺序
        initImage();//初始化图片
        this.setVisible(true);
    }


    private void shuffleImage() {
        //-----------打乱一维数组的顺序----------
        int[] arr = {0,1,2,3,4,5,6,7,8};
        //获取随机索引0-9范围内
        Random random = new Random();
        int index = random.nextInt(arr.length);
        //将一维数组中的元素值与索引值进行交换
        for (int i = 0; i < arr.length; i++) {
            int temp = arr[index];
            arr[index] = arr[i];
            arr[i] = temp;
        }
        //-------将一维数组的值放入二维数组中--------
        //--------要理解为什么要转为二维数组---------
        /*int n = 0;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                arr1[i][j] = arr[n];
                n++;
            }
        }*/
        //--------这段代码理解不了~用来移动图片，记录空白的xy值的···········-----
        for (int i = 0; i < arr.length; i++) {
            if(arr[i]==0){
                x=i/3;
                y=i%3;
            }
            arr1[i/3][i%3]=arr[i];
        }
    }

    private void initImage() {
        //删除已经加载的所有图片
        this.getContentPane().removeAll();

        //返回值为true:加载胜利的图片
        if(victory()){
            JLabel jLabel = new JLabel(new ImageIcon("D:\\AAQX\\Java\\Project_Practice\\src\\a00_ImageGame\\image\\victory.png"));
            jLabel.setBounds(200,200,100,100);
            this.getContentPane().add(jLabel);
        };
        //统计步数
        JLabel stepCount = new JLabel("步数:"+count);
        stepCount.setBounds(50,50,200,200);
        this.getContentPane().add(stepCount);

        //两次for循环，相当于二维数组
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                //--------------这里将打乱数组函数中获取到的二维数组的值传递给num，那么加载图片路径的顺序就是按照这个num来的
                int num = arr1[i][j];
                //创建ImageIcon对象放图片
                ImageIcon imageIcon = new ImageIcon(path+num+".jpg");
                //创建JLabel对象：是个容器
                JLabel jLabel = new JLabel(imageIcon);
                //设置边框
                jLabel.setBorder(new BevelBorder(1));//setBorder是个接口，BevelBorder是一个是实现了该接口的类
                this.getContentPane();
                jLabel.setBounds(j*120+90,i*120+90,120,120);
                //将ImageIcon放入JLabel对象中
                this.add(jLabel);
            }
        }

        //添加背景图:注意：先加载的图在上面
        ImageIcon imageIcon1 = new ImageIcon(path+"backGround.png");
        JLabel jLabel1 = new JLabel(imageIcon1);//将imageIcon图放在jLabel容器中
        jLabel1.setBounds(0,0,600,600);
        this.getContentPane().add(jLabel1);//获取隐藏容器将jLabel放进去

        //刷新一下界面
        this.getContentPane().repaint();
    }

    private void initJMenuBar() {
        //创建整个的菜单对象
        JMenuBar jMenuBar = new JMenuBar();
        //功能和关于我们选项
        JMenu functionJMenu  = new JMenu("功能");
        JMenu aboutJMenu  = new JMenu("关于我们");

        //将下拉菜单添加到选项中
        functionJMenu.add(replayItem);
        functionJMenu.add(reLoginItem);
        functionJMenu.add(closeItem);

        aboutJMenu.add(accountItem);
        //将菜单的两个选项添加到菜单中
        jMenuBar.add(functionJMenu);
        jMenuBar.add(aboutJMenu);

        //----给条目绑定事件
        replayItem.addActionListener(this);
        reLoginItem.addActionListener(this);
        closeItem.addActionListener(this);
        accountItem.addActionListener(this);

        //给整个界面设置菜单
        this.setJMenuBar(jMenuBar);
    }

    private void initJFrame() {
        this.setSize(600,600);
        this.setTitle("拼图单机版 v1.0");
        this.setAlwaysOnTop(true);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(3);//设置默认的关闭模式
        //给整个窗体绑定事件addKeyListener
        this.addKeyListener(this);
        //取消默认的居中放置
        this.setLayout(null);
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    //按下不松手时，会调用这个方法
    @Override
    public void keyPressed(KeyEvent e) {
        //如果长按A，就删除界面中的所有图片，然后重新加载第一张完整的图片，加载背景图
        if(e.getKeyCode()==65){
            this.getContentPane().removeAll();
            JLabel jLabel = new JLabel(new ImageIcon("D:\\AAQX\\Java\\Project_Practice\\src\\a00_ImageGame\\image\\all.png"));
            jLabel.setBounds(50,50,500,500);
            this.getContentPane().add(jLabel);

            //添加背景图:注意：先加载的图在上面
            ImageIcon imageIcon1 = new ImageIcon("src\\a00_ImageGame\\image\\backGround.png");
            JLabel jLabel1 = new JLabel(imageIcon1);//将imageIcon图放在jLabel容器中
            jLabel1.setBounds(0,0,800,800);
            this.getContentPane().add(jLabel1);//获取隐藏容器将jLabel放进去

            //刷新一下界面
            this.getContentPane().repaint();
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        //判断游戏是否胜利：如果是胜利，那么直接结束，不能再执行后面的移动代码
        if(victory()){
            return;
        }
        //对上下左右进行判断：左37
        int code = e.getKeyCode();
        if(code == 37){
            System.out.println("向左移动");
            //如果移动已经到边边了，就根据二维数组的索引值结束该方法，防止报错
            if(y==0){
                return;
            }
            arr1[x][y] = arr1[x][y-1];
            arr1[x][y-1] = 0;
            //更新空白方块xy的位置
            y--;
            //每移动一次，计数器+1
            count++;
            initImage();
        } else if (code == 38) {
            System.out.println("向上移动");
            if(x==0){
                return;
            }
            arr1[x][y] = arr1[x-1][y];
            arr1[x-1][y] = 0;
            //更新空白方块xy的位置
            x--;
            count++;
            initImage();
        }else if (code == 39) {
            System.out.println("向右移动");
            if(y==2){
                return;
            }
            arr1[x][y] = arr1[x][y+1];
            arr1[x][y+1] = 0;
            //更新空白方块xy的位置
            y++;
            count++;
            initImage();

        }else if (code == 40) {
            System.out.println("向下移动");
            if(x==2){
                return;
            }
            //xy表示空白方块，x,y+1表示其下方的数字->将两者的数字进行一个交换
            arr1[x][y] = arr1[x+1][y];
            arr1[x+1][y] = 0;
            //更新空白方块xy的位置
            x++;
            count++;
            initImage();
        } else if (code==65) {//A：查看原始图片
            initImage();
        } else if (code==87) {//W：一键生成成功图片
            arr1=new int[][]{
                    {1,2,3},{4,5,6},{7,8,0}
            };
            initImage();
        }
    }
    //判断arr1中数组的值是否与win中的值相同，相同则返回true，否则flase
    public boolean victory(){
        //二维数组的遍历
        for (int i = 0; i < arr1.length; i++) {
            for (int j = 0; j < arr1[i].length; j++) {
                if(arr1[i][j]!=win[i][j]){
                    return false;
                }
            }
        }
        return true;
    }

    //
    @Override
    public void actionPerformed(ActionEvent e) {
        //比较：现在是点击的哪一个条目
        if(e.getSource()==replayItem){
            System.out.println("重新游戏");
            //再次打乱二维数组的游戏——>计数器清0->加载图片
            shuffleImage();
            count=0;
            initImage();

        } else if (e.getSource()==reLoginItem) {
            System.out.println("重新登录");
            //关闭当前的登录界面——>打开登录界面
            this.setVisible(false);
            new LoginJFrame();
        } else if (e.getSource()==closeItem) {
            System.out.println("关闭游戏");
            System.exit(0);//关闭虚拟机
        } else if (e.getSource()==accountItem) {
            System.out.println("公众号");
            //弹框->图片
            //创建一个弹框对象
            JDialog jDialog = new JDialog();
            JLabel jLabel = new JLabel(new ImageIcon("D:\\AAQX\\Java\\Project_Practice\\src\\a00_ImageGame\\image\\img.png"));
            jLabel.setBounds(0,0,200,200);
            jDialog.getContentPane().add(jLabel);
            jDialog.setSize(500,500);
            jDialog.setAlwaysOnTop(true);
            jDialog.setLocationRelativeTo(null);
            jDialog.setModal(true);//弹框不关闭就无法进行下面的操作
            jDialog.setVisible(true);
        }
    }
}
